#include "CreateObject.h"

CreateObject::CreateObject(NxScene* scene):m_scene(scene)
{
}

CreateObject::~CreateObject(void)
{
}

NxActor* CreateObject::CreateBox(const NxVec3& size, const NxVec3& position, const NxVec3& dFsFR, float mass)
{
	// shape of the box
	NxBoxShapeDesc boxDesc;
	boxDesc.mass = mass;
	boxDesc.dimensions.set(size.x, size.y, size.z);

	//create the material of the box
	NxMaterialDesc material;
	material.dynamicFriction = dFsFR.x;
	material.staticFriction = dFsFR.y;
	material.restitution = dFsFR.z;
	int materialIndex = m_scene->createMaterial(material)->getMaterialIndex();

	boxDesc.materialIndex = materialIndex;

	//actor description
	NxActorDesc actorDesc;
	actorDesc.shapes.pushBack(&boxDesc);
	NxBodyDesc bodyDesc;
	actorDesc.body			= &bodyDesc;
	actorDesc.density		= 10.0f;
	actorDesc.globalPose.t	= position;	

	//create the actor
	assert(actorDesc.isValid());
	NxActor *pActor = m_scene->createActor(actorDesc);	
	assert(pActor);


	return pActor;
}

NxActor* CreateObject::CreateKinematicBox(const NxVec3& size, const NxVec3& position, const NxVec3& rotation, const NxVec3& dFsFR)
{
	//create the shape of the box
	NxBoxShapeDesc boxDesc;
	boxDesc.dimensions.set(size);
	boxDesc.localPose.M.rotX(rotation.x);
	boxDesc.localPose.M.rotY(rotation.y);
	boxDesc.localPose.M.rotZ(rotation.z);

	//create the material of the box
	NxMaterialDesc material;
	material.dynamicFriction = dFsFR.x;
	material.staticFriction = dFsFR.y;
	material.restitution = dFsFR.z;
	int materialIndex = m_scene->createMaterial(material)->getMaterialIndex();

	boxDesc.materialIndex = materialIndex;

	//create the actor
	NxActorDesc actorDesc;
	actorDesc.shapes.pushBack(&boxDesc);
	actorDesc.globalPose.t	= position;
	

	//assert that the actor description is valid and create the actor
	assert(actorDesc.isValid());
	NxActor *pActor = m_scene->createActor(actorDesc);	
	assert(pActor);


	return pActor;
}
NxActor* CreateObject::CreateGroundPlane()
{
	// Create a plane with default descriptor
    NxPlaneShapeDesc planeDesc;

    NxActorDesc actorDesc;

    actorDesc.shapes.pushBack(&planeDesc);
    return m_scene->createActor(actorDesc);
}
NxActor* CreateObject::CreateSphere(const NxVec3& position, float radius, float mass, float dynamicFriction, float staticFriction, float restitution)
{
	//shape descriptor
	NxSphereShapeDesc sphereDesc;
	sphereDesc.radius = radius;
	sphereDesc.mass = mass;

	//material descriptor
	NxMaterialDesc material;
	material.dynamicFriction = dynamicFriction;
	material.staticFriction = staticFriction;
	material.restitution = restitution;
	int indexMaterial = m_scene->createMaterial(material)->getMaterialIndex();

	sphereDesc.materialIndex = indexMaterial;

	//set the actor descriptor
	NxActorDesc actorDesc;
	actorDesc.shapes.pushBack(&sphereDesc);
	NxBodyDesc bodyDesc;
	actorDesc.body = &bodyDesc;
	actorDesc.density = 10.0f;
	actorDesc.globalPose.t = position;	
	return m_scene->createActor(actorDesc);
}
NxActor* CreateObject::CreateKinematicSphere(float radius, const NxVec3& position)
{
	// Add a single-shape actor to the scene
	NxActorDesc actorDesc;
	
	// The actor has one shape, a sphere, 1m on radius
	NxSphereShapeDesc sphereDesc;
	sphereDesc.radius		= radius;

	actorDesc.shapes.pushBack(&sphereDesc);
	actorDesc.globalPose.t	= position;	
	return m_scene->createActor(actorDesc);
}

NxActor* CreateObject::CreateWheel(const NxVec3& position, float radius)
{
	
	NxWheelShapeDesc wheelDesc;
	wheelDesc.setToDefault();
	wheelDesc.radius = radius;

	NxActorDesc actorDesc;
	actorDesc.shapes.push_back(&wheelDesc);
	NxBodyDesc body;
	actorDesc.body = &body;
	actorDesc.density = 10.0f;
	actorDesc.globalPose.t = position;
	actorDesc.globalPose.M.id();

	return m_scene->createActor(actorDesc);
}